/*****************************************************************************************************************
 * memory_bit_stream.cpp
 * 描述:参考多人网络游戏框架代码编写
 * 作者:xhome
 * 时间:2020/5/20
 ****************************************************************************************************************/

#include "memory_bit_stream.h"


void OutputMemoryBitStream::write_bits(uint8_t in_data, uint32_t in_bit_count)
{
    uint32_t next_bit_head = bit_head_ + static_cast<uint32_t>(in_bit_count);


    if(next_bit_head > bit_capacity_)
    {
        //std::max  推导出最大值.
        realloc_buffer(std::max(bit_capacity_*2, next_bit_head));
    }

    //计算buffer中字节偏移量
    //计算缓冲区中的字节偏移量, 把头除以8, 和最后3位的位偏移量
    uint32_t byte_offset = bit_head_ >> 3;
    uint32_t bit_offset = bit_head_ & 0x7; //111

    //设bit_offset 0111 后3位有效 7
    // 0xff << 7  ==> 0xff0  ~ ==> 0x0f
    uint8_t current_mask = ~(0xff << bit_offset);  //本操作目的，将32位变为8位.

    buffer_[byte_offset] = (buffer_[byte_offset] & current_mask)|(in_data << bit_offset);

    //计算当前字节还剩余多少位没有被使用.
    uint32_t bits_free_this_byte = 8 - bit_offset;

    if(bits_free_this_byte < in_bit_count)
    {
        buffer_[byte_offset + 1] = in_data >> bits_free_this_byte;
    }

    bit_head_ = next_bit_head;
}

void OutputMemoryBitStream::write_bits(const void *in_data, uint32_t in_bit_count)
{
    const char * src_byte = static_cast<const  char *>(in_data);
    while(in_bit_count > 8)
    {
        //一个字节一个字节的写入.
        write_bits(*src_byte, 8);
        ++src_byte;
        in_bit_count -=8;
    }
    //写任何东西, 写最后一个字节.
    if(in_bit_count > 0)
    {
        write_bits(*src_byte, in_bit_count);
    }

}

void OutputMemoryBitStream::realloc_buffer(uint32_t in_new_bit_length)
{
    if(buffer_ == nullptr){
        buffer_ = static_cast<char *>(std::malloc(in_new_bit_length >> 3));
        memset(buffer_, 0, in_new_bit_length >> 3);
    }
    else{

        char * tempbuffer = static_cast<char *>(std::malloc(in_new_bit_length >> 3));
        memset(tempbuffer, 0, in_new_bit_length >> 3);
        memcpy(tempbuffer, buffer_, bit_capacity_ >> 3);

        std::free(buffer_);
        buffer_ = tempbuffer;
    }

    bit_capacity_ = in_new_bit_length;
}


void InputMemoryBitStream::read_bits(uint8_t &out_data, uint32_t in_bit_count)
{
    uint32_t byte_offset = bit_head_ >>3;
    uint32_t bit_offset = bit_head_ & 0x7;

    out_data = static_cast<uint8_t >(buffer_[byte_offset]) >> bit_offset;
    uint32_t bits_free_this_byte = 8 - bit_offset;

    if(bits_free_this_byte < in_bit_count)
    {
        out_data |= static_cast<uint8_t >(buffer_[byte_offset+1]) << bits_free_this_byte;
    }

    out_data &= (~(0x00ff << in_bit_count));

    bit_head_ += in_bit_count;
}

void InputMemoryBitStream::read_bits(void *out_data, uint32_t in_bit_count)
{
    uint8_t * dest_byte = reinterpret_cast<uint8_t *>(out_data);

    while(in_bit_count > 8){
        read_bits(*dest_byte, 8);
        ++dest_byte;

        in_bit_count -= 8;
    }
    if(in_bit_count > 0)
    {
        read_bits(*dest_byte, in_bit_count);
    }
}





























